package com.xbongbong.saas.model.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.model.PaasFormDataEsModel;
import com.xbongbong.paas.elasticsearch.pojo.dto.DeleteDTO;
import com.xbongbong.paas.elasticsearch.pojo.dto.InsertDTO;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.util.DataUtil;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.BusinessTypeErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.formdata.pojo.SaasSpecialParamPojo;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.invoice.pojo.dto.InvoiceAmountDetailDTO;
import com.xbongbong.pro.invoice.pojo.dto.InvoiceAmountDetailGetDTO;
import com.xbongbong.pro.invoice.pojo.dto.SalesInvoiceAmountHandleDTO;
import com.xbongbong.pro.invoice.pojo.vo.InvoiceAmountDetailVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.InvoiceConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.dao.InvoiceDao;
import com.xbongbong.saas.domain.entity.InvoiceRelationshipEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.domain.entity.ext.InvoiceEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.ShowTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.base.InvoiceBaseEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.help.AddMapHelp;
import com.xbongbong.saas.help.InvoiceCommonHelp;
import com.xbongbong.saas.help.ShowFormatHelp;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.FundSetModel;
import com.xbongbong.saas.model.InvoiceModel;
import com.xbongbong.saas.model.InvoiceRelationshipModel;
import com.xbongbong.saas.model.InvoiceSubDataModel;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.model.PaymentSheetModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.saas.util.StandardizeDataUtil;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleFromFormData;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

/**
 * @author feng.zheng
 * @version v1.0
 * @date 2019/1/25 15:27
 * @since v1.0
 */
@Service("invoiceModel")
public class InvoiceModelImpl implements InvoiceModel {

    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private InvoiceDao invoiceDao;
    @Resource
    private PaasFormDataEsModel paasFormDataEsModel;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;
    @Resource
    private InvoiceSubDataModel invoiceSubDataModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private ShowFormatHelp showFormatHelp;
    @Resource
    private EsHelper esHelper;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private InvoiceRelationshipModel invoiceRelationshipModel;
    @Resource
    private PaymentModel paymentModel;
    @Resource
    private PaymentSheetModel paymentSheetModel;
    @Resource
    private FundSetModel fundSetModel;

    @Override
    public Integer insert(InvoiceEntityExt entity) throws XbbException {
        //TODO  先进行数据库的插入动作
        long now = DateUtil.getInt();
        entity.setAddTime(now);
        entity.setUpdateTime(now);

        paasFormSubDataModel.transferSingleSubForm(entity, IndexTypeEnum.IDX_SAAS_INVOICE_EXPRESS);
        paasFormSubDataModel.transferSubForm(entity, IndexTypeEnum.IDX_SAAS_INVOICE_SUB);
        StandardizeDataUtil.standardizeNotString(entity);
        Integer success = invoiceDao.insert(entity);
        PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
        BeanUtil.copyProperties(entity, paasFormDataEntity);
        InsertDTO insertDTO = paasEsModel.getSaveDTO(paasFormDataEntity, IndexTypeEnum.IDX_SAAS_INVOICE);
        paasEsModel.insert(insertDTO);

        paasFormSubDataModel.insertSingleSubFormData(entity, IndexTypeEnum.IDX_SAAS_INVOICE_EXPRESS);
        paasFormSubDataModel.insertSubFormData(entity, IndexTypeEnum.IDX_SAAS_INVOICE_SUB);
        return success;
    }

    @Override
    public Integer update(InvoiceEntityExt entity) throws XbbException {
        long now = DateUtil.getInt();
        entity.setUpdateTime(now);

        paasFormSubDataModel.transferSingleSubForm(entity, IndexTypeEnum.IDX_SAAS_INVOICE_EXPRESS);
        paasFormSubDataModel.transferSubForm(entity, IndexTypeEnum.IDX_SAAS_INVOICE_SUB);
        StandardizeDataUtil.standardizeNotString(entity);
        Integer success = invoiceDao.update(entity);
        Integer updateSingleSub = paasFormSubDataModel.updateSubFormData(entity, IndexTypeEnum.IDX_SAAS_INVOICE_EXPRESS);
        Integer updateSub = paasFormSubDataModel.updateSubFormData(entity, IndexTypeEnum.IDX_SAAS_INVOICE_SUB);
        if (Objects.equals(1, success) || Objects.equals(1, updateSingleSub) || Objects.equals(1, updateSub)) {
            // 更新时间
            success = invoiceDao.updateTime(now + 1, entity.getId(), entity.getCorpid());
            // 更新es
            PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
            BeanUtil.copyProperties(entity, paasFormDataEntity, false);
            InsertDTO insertDTO = paasEsModel.getSaveDTO(paasFormDataEntity, IndexTypeEnum.IDX_SAAS_INVOICE);
            paasEsModel.update(insertDTO);


        }
        if (Objects.nonNull(entity.getSubFormData()) && !entity.getSubFormData().isEmpty()) {
            entity.getData().putAll(entity.getSubFormData());
        }
        if (Objects.nonNull(entity.getSingleSubFormData()) && !entity.getSingleSubFormData().isEmpty()) {
            entity.getData().putAll(entity.getSingleSubFormData());
        }
        return success;
    }

    @Override
    public List<InvoiceEntityExt> findEntitys(Map<String, Object> param) {
        List<InvoiceEntityExt> entitys = invoiceDao.findEntitys(param);
        Object corpid = param.get(ParameterConstant.CORPID);
        if (Objects.nonNull(corpid)) {
            paasFormSubDataModel.findSubEntity4Invoice(entitys, corpid.toString());
            paasFormSubDataModel.findSubEntity(corpid.toString(), entitys, IndexTypeEnum.IDX_SAAS_INVOICE_SUB);
        }
        return entitys;
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return invoiceDao.getEntitysCount(param);
    }

    @Override
    public InvoiceEntityExt getByKey(Long key, String corpid) {
        InvoiceEntityExt invoiceEntityExt = invoiceDao.getByKey(key, corpid);
        paasFormSubDataModel.findSubEntity4Invoice(Collections.singletonList(invoiceEntityExt), corpid);
        paasFormSubDataModel.findSubEntity(corpid, Collections.singletonList(invoiceEntityExt), IndexTypeEnum.IDX_SAAS_INVOICE_SUB);
        return invoiceEntityExt;
    }


    /**
     * 快速更新
     *
     * @param idIn  参数
     * @param corpid 公司id
     * @return 成功与否
     * @throws XbbException 异常
     */

    @Override
    public Integer deleteBatch(List<Long> idIn, String corpid, Integer del) throws XbbException {
        Integer integer = invoiceDao.deleteBatchAppointDel(idIn, corpid, del);
        paasEsModel.deleteBatch(idIn, corpid, del, IndexTypeEnum.IDX_SAAS_INVOICE);

        paasFormSubDataModel.deleteBatchByDataId(idIn, corpid, IndexTypeEnum.IDX_SAAS_INVOICE_EXPRESS, DelEnum.DELETE_SUBFORM);
        paasFormSubDataModel.deleteBatchByDataId(idIn, corpid, IndexTypeEnum.IDX_SAAS_INVOICE_SUB, DelEnum.DELETE_SUBFORM);
        return integer;
    }

    @Override
    public Integer deleteByKey(Long key,String corpid) throws XbbException{
        DeleteDTO deleteDTO = new DeleteDTO();
        deleteDTO.setEsId(corpid+"_"+key);
        deleteDTO.setIndexTypeEnum(IndexTypeEnum.IDX_SAAS_INVOICE);
        paasEsModel.delete(deleteDTO);
        Integer integer = invoiceDao.deleteByKey(key, corpid);
        paasFormSubDataModel.deleteByDataId(key, corpid, IndexTypeEnum.IDX_SAAS_INVOICE_EXPRESS);
        paasFormSubDataModel.deleteByDataId(key, corpid, IndexTypeEnum.IDX_SAAS_INVOICE_SUB);
        return integer;
    }

    @Override
    public Integer deleteByKeyAppointDel(Long id, String corpid, DelEnum delEnum) throws XbbException {
        DeleteDTO deleteDTO = new DeleteDTO();
        deleteDTO.setEsId(corpid + "_" + id);
        deleteDTO.setIndexTypeEnum(IndexTypeEnum.IDX_SAAS_INVOICE);
        paasEsModel.delete(deleteDTO, delEnum);
        Integer integer = invoiceDao.deleteByKeyAppointDel(id, corpid, delEnum.getDel());
        paasFormSubDataModel.deleteByDataId(id, corpid, IndexTypeEnum.IDX_SAAS_INVOICE_EXPRESS);
        paasFormSubDataModel.deleteByDataId(id, corpid, IndexTypeEnum.IDX_SAAS_INVOICE_SUB);
        return integer;
    }

    @Override
    public Integer updateBatch(List<UpdateDataEntity> updateList, String corpid) throws XbbException {
        //1. 先拿到子表单数据
        List<UpdateDataEntity> subList = DataUtil.getUpdateSubDataList(updateList);
        // 2. 主表删掉子表单数据
        DataUtil.removeSubDataInData(updateList);
        Integer integer = 0;
        if (CollectionsUtil.isNotEmpty(updateList)) {
            StandardizeDataUtil.standardizeList(updateList);
            integer = invoiceDao.updateBatch(updateList, corpid);
            paasEsModel.updateBatchMuchField(updateList, IndexTypeEnum.IDX_SAAS_INVOICE);
        }
        if (!subList.isEmpty()) {
            invoiceSubDataModel.updateBatch(subList, corpid);
        }
        return integer;
    }

    @Override
    public Integer updateBatch(List<UpdateDataEntity> updateList, String corpid, WriteRequest.RefreshPolicy refreshPolicy) throws XbbException {
        //1. 先拿到子表单数据
        List<UpdateDataEntity> subList = DataUtil.getUpdateSubDataList(updateList);
        // 2. 主表删掉子表单数据
        DataUtil.removeSubDataInData(updateList);
        Integer integer = 0;
        if (CollectionsUtil.isNotEmpty(updateList)) {
            StandardizeDataUtil.standardizeList(updateList);
            integer = invoiceDao.updateBatch(updateList, corpid);
            paasEsModel.updateBatchMuchField(updateList, IndexTypeEnum.IDX_SAAS_INVOICE, refreshPolicy);
        }
        if (!subList.isEmpty()) {
            invoiceSubDataModel.updateBatch(subList, corpid);
        }
        return integer;
    }

    @Override
    public Integer updateBatch(List<UpdateDataEntity> updateList, String corpid,boolean needThrow) throws XbbException {
        //1. 先拿到子表单数据
        List<UpdateDataEntity> subList = DataUtil.getUpdateSubDataList(updateList);
        // 2. 主表删掉子表单数据
        DataUtil.removeSubDataInData(updateList);
        Integer integer = 0;
        if (CollectionsUtil.isNotEmpty(updateList)) {
            StandardizeDataUtil.standardizeList(updateList);
            integer = invoiceDao.updateBatch(updateList, corpid);
            paasEsModel.updateBatchMuchField(updateList, IndexTypeEnum.IDX_SAAS_INVOICE,needThrow);
        }
        if (!subList.isEmpty()) {
            invoiceSubDataModel.updateBatch(subList, corpid);
        }
        return integer;
    }

    /**
     * 数据还原
     * @param dataIdList
     * @param corpid
     * @param del
     * @throws XbbException
     */
    @Override
    public Integer restoreBatch(List<Long> dataIdList, String corpid, Integer del) throws XbbException {
        Integer count = invoiceDao.restoreBatch(dataIdList, corpid, del);
        updateBatchDel(dataIdList, corpid, del);

        paasFormSubDataModel.restoreBatch(dataIdList, corpid, IndexTypeEnum.IDX_SAAS_INVOICE_EXPRESS);
        paasFormSubDataModel.restoreBatch(dataIdList, corpid, IndexTypeEnum.IDX_SAAS_INVOICE_SUB);
        return count;
    }

    private void updateBatchDel(List<Long> dataIdList, String corpid, Integer del) throws XbbException{
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("del", del);
        map.put("updateTime",DateTimeUtil.getInt());
        paasFormDataEsModel.updateBatch(dataIdList, corpid, map, IndexTypeEnum.IDX_SAAS_INVOICE);
    }

    @Override
    public List<InvoiceEntityExt> getAllInvoiceList(String corpid) throws XbbException{
        List<InvoiceEntityExt> allInvoiceList = invoiceDao.getAllInvoiceList(corpid);
        paasFormSubDataModel.findSubEntity4Invoice(allInvoiceList, corpid);
        paasFormSubDataModel.findSubEntity(corpid, allInvoiceList, IndexTypeEnum.IDX_SAAS_INVOICE_SUB);
        return allInvoiceList;
    }

    @Override
    public List<InvoiceEntityExt> findEntitysWithoutSub(Map<String, Object> param) {
        return invoiceDao.findEntitys(param);
    }

    /**
     * 编辑时改变解释
     *
     * @param formatExplainDTO 入参
     * @throws XbbException 异常
     */
    /**
     * 编辑时改变解释
     *
     * @param formatExplainDTO 入参
     * @throws XbbException 异常
     */
    @Override
    public void formatUpdateExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        List<FieldAttrEntity> explainList = formatExplainDTO.getExplainList();
        SaasSpecialParamPojo saasSpecialParamPojo = formatExplainDTO.getSaasSpecialParamPojo();
        PaasFormDataEntityExt dataEntity = formatExplainDTO.getDataEntity();
        JSONObject dataList = formatExplainDTO.getResult();
        //是否红冲发票
        boolean isRed = Objects.equals(BasicConstant.ONE, dataList.getIntValue(InvoiceBaseEnum.IS_RED.getAttr()));
        //是否作废发票
        boolean isCancel = Objects.equals(BasicConstant.ONE, dataList.getIntValue(InvoiceBaseEnum.IS_CANCEL.getAttr()));
        //是否被红冲过
        boolean hasRed = Objects.equals(BasicConstant.ONE, dataList.getIntValue(InvoiceBaseEnum.HAS_RED.getAttr()));
        //获取数据创建时的应收模式
        Long modelType = dataEntity.getSysLong10();
        //获取当前正处于的应收模式
        Long nowModelType = fundSetModel.getModelType(formatExplainDTO.getCorpid(),XbbRefTypeEnum.CRM);
        //是否关联客户
        String isLinkCustomer = FastJsonHelper.getStringOrDefaultFromFormData(dataList, InvoiceEnum.CUSTOMER_NAME.getAttr(), "");
        //是否关联合同
        String isLinkContract = FastJsonHelper.getStringOrDefaultFromFormData(dataList, InvoiceEnum.CONTRACT_ID.getAttr(), "");
        //获取销项发票的审批状态
        Integer flowStatus = dataEntity.getFlowStatus();
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.CUSTOMER_NAME.getAttr())) {
                fieldAttrEntity.setEditable(BasicConstant.ZERO);
            } else if (isRed && Objects.equals(fieldAttrEntity.getAttr(), InvoiceBaseEnum.ORIGIN_ID.getAttr())) {
                fieldAttrEntity.setShowType(ShowTypeEnum.EDIT_DETAIL.getCode());
                fieldAttrEntity.setEditable(BasicConstant.ZERO);
            } else if(Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.INVOICE_DATE.getAttr())) {
                if (Objects.equals(flowStatus, FlowStatusEnum.NOT_NEED_APPROVAL.getType()) || Objects.equals(flowStatus,FlowStatusEnum.PASS.getType())){
                    //1、对于无需审批的销项发票，只有手动创建应收、按出库产生应收模式下允许编辑开票日期
                    if(Objects.equals(modelType, ModelTypeEnum.INVOICE.getCode()) || Objects.equals(nowModelType, ModelTypeEnum.INVOICE.getCode())){
                        fieldAttrEntity.setEditable(BasicConstant.ZERO);
                    }
                }else if ((Objects.equals(flowStatus,FlowStatusEnum.IN_APPROVAL.getType()) || Objects.equals(flowStatus,FlowStatusEnum.APPROVAL_PENDING.getType()))){
                    //2、对于审批中销项发票,手动创建应收、按出库产生应收模式下满足：1、没被红冲过 2、不是红冲发票 3、不是作废发票 4、关联了客户没有关联合同
                    boolean flag = Objects.equals(modelType, ModelTypeEnum.INVOICE.getCode()) || Objects.equals(nowModelType, ModelTypeEnum.INVOICE.getCode())
                            || isRed
                            || isCancel
                            || hasRed
                            || StringUtils.isEmpty(isLinkCustomer)
                            || !StringUtils.isEmpty(isLinkContract);
                    if(flag) {
                        fieldAttrEntity.setEditable(BasicConstant.ZERO);
                    }
                }
            }
        }
        if (saasSpecialParamPojo != null && Objects.equals(saasSpecialParamPojo.getFromRed(), BasicConstant.ONE)) {
            Long id = dataEntity.getId();
            String esData = StringConstant.JSON_DATA + StringConstant.POINT;
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery(esData + InvoiceEnum.ORIGIN_ID.getAttr(), id));
            boolQueryBuilder.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD , formatExplainDTO.getCorpid()));
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_INVOICE.getType()));
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(boolQueryBuilder);
            SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_INVOICE.getIndex());
            searchRequest.source(sourceBuilder);
            Long count = xbbElasticsearchRestTemplate.count(searchRequest, PaasFormDataEntityExt.class);
            String sheetNo = dataEntity.getSerialNo();
            if (count == null) {
                count = 0L;
            }
            dataEntity.setSerialNo(sheetNo + StringConstant.POINT + (count.intValue() + 1));
            Double totalMoney = FastJsonHelper.getDoubleOrDefaultFromFormData(dataList, InvoiceEnum.TOTAL_MONEY.getAttr(), 0D);
            Double redTotalMoney = getRedTotalMoney(id, formatExplainDTO.getCorpid());
            JSONArray originArr = new JSONArray();
            JSONObject originObj = new JSONObject();
            originObj.put(StringConstant.SAAS_LINK_BUSINESS_ID, id);
            originObj.put(StringConstant.SAAS_LINK_BUSINESS_NAME, sheetNo);
            originArr.add(originObj);
            dataList.put(InvoiceEnum.ORIGIN_ID.getAttr(), originArr);
            dataList.put(InvoiceEnum.TOTAL_MONEY.getAttr(), totalMoney + redTotalMoney);
            dataList.put(InvoiceEnum.INVOICE_DATE.getAttr(), DateTimeUtil.getInt());
            for (FieldAttrEntity fieldAttrEntity : explainList) {
                if (Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.ORIGIN_ID.getAttr())) {
                    fieldAttrEntity.setShowType(ShowTypeEnum.EDIT_DETAIL.getCode());
                    fieldAttrEntity.setEditable(BasicConstant.ZERO);
                }
                if (Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.TOTAL_MONEY.getAttr())) {
                    fieldAttrEntity.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.RED_INVOICE_AMOUNT));
                }
                if (Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.CUSTOMER_NAME.getAttr())) {
                    fieldAttrEntity.setEditable(BasicConstant.ZERO);
                }
                if (Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.CONTRACT_ID.getAttr())) {
                    fieldAttrEntity.setEditable(BasicConstant.ZERO);
                }
                if (Objects.equals(fieldAttrEntity.getAttr(), InvoiceEnum.PAYMENT_ID.getAttr())) {
                    fieldAttrEntity.setEditable(BasicConstant.ZERO);
                }
            }
        }
    }

    /**
     * 获取红冲总金额
     *
     * @param originId 原始id
     * @param corpid   公司id
     * @return double
     * @throws XbbException 异常
     */
    @Override
    public Double getRedTotalMoney(Long originId, String corpid) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.FLOW_STATUS_IN, Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType()));
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<PaasFormDataEntityExt> paasFormDataEntityExts = paasEsModel.selectByOneCondition(RedundantTemplateTypeEnum.INVOICE.getCode(), InvoiceEnum.ORIGIN_ID.getAttr(), originId, param, IndexTypeEnum.IDX_SAAS_INVOICE);
        Double redTotalMoney = 0D;
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
            Double money = getDoubleFromFormData(paasFormDataEntityExt.getData(), InvoiceEnum.TOTAL_MONEY.getAttr());
            if (money == null) {
                money = 0D;
            }
            redTotalMoney += money;
        }
        return redTotalMoney;
    }

    /**
     * 编辑时将获取数据格式化
     *
     * @param formDataUpdateGetDTO saas编辑数据
     * @param result               要返回的jsonObject
     * @throws XbbException 业务异常
     * @author feng.zheng
     * @date 2019/1/22 15:28
     */
    @Override
    public void formatData(SaasAnalysisDataDTO formDataUpdateGetDTO, JSONObject result) throws XbbException {
        showFormatHelp.formatLinkBusiness4Show(result, InvoiceEnum.CUSTOMER_NAME.getAttr(), InvoiceEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), InvoiceEnum.CUSTOMER_NAME.getFieldType());
        showFormatHelp.formatLinkBusiness4Show(result, InvoiceEnum.CONTRACT_ID.getAttr(), InvoiceEnum.CONTRACT_ID_LINK_TEXT.getAttr(), InvoiceEnum.CONTRACT_ID.getFieldType());
        showFormatHelp.formatLinkBusiness4Show(result, InvoiceEnum.PAYMENT_ID.getAttr(), InvoiceEnum.PAYMENT_ID_LINK_TEXT.getAttr(), InvoiceEnum.PAYMENT_ID.getFieldType());
        showFormatHelp.formatLinkBusiness4Show(result, InvoiceEnum.PAYMENT_SHEET_ID.getAttr(), InvoiceEnum.PAYMENT_SHEET_ID_LINK_TEXT.getAttr(), InvoiceEnum.PAYMENT_SHEET_ID.getFieldType());
        showFormatHelp.formatLinkBusiness4Show(result, InvoiceEnum.ORIGIN_ID.getAttr(), InvoiceEnum.ORIGIN_ID_LINK_TEXT.getAttr(), InvoiceEnum.ORIGIN_ID.getFieldType());
    }

    @Override
    public InvoiceAmountDetailVO getInvoiceAmountDetail(InvoiceAmountDetailGetDTO invoiceAmountDetailGetDTO) throws XbbException{
        if(!Objects.equals(invoiceAmountDetailGetDTO.getBusinessType(), XbbRefTypeEnum.INVOICE.getCode())){
            throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        //如果是从获取金额明细接口过来
        if(Objects.equals(invoiceAmountDetailGetDTO.getIsGetDetail(),BasicConstant.ONE) && Objects.nonNull(invoiceAmountDetailGetDTO.getInvoiceId())){
            invoiceAmountDetailGetDTO.setIsEdit(BasicConstant.ONE);
        }
        //红冲编辑需要知道原发票id
        List<Long> redIdAndOrigialList = new ArrayList<>();
        Long originId = 0L;
        boolean redFlag = (Objects.equals(invoiceAmountDetailGetDTO.getIsRed(),BasicConstant.ONE) && Objects.equals(invoiceAmountDetailGetDTO.getIsEdit(),BasicConstant.ONE)) || Objects.equals(invoiceAmountDetailGetDTO.getFormRed(),BasicConstant.ONE);
        //红冲编辑时
        if(Objects.nonNull(invoiceAmountDetailGetDTO.getInvoiceId()) && Objects.equals(invoiceAmountDetailGetDTO.getIsRed(),BasicConstant.ONE) && Objects.equals(invoiceAmountDetailGetDTO.getIsEdit(),BasicConstant.ONE)){
            InvoiceEntityExt invoiceEntityExt = getByKey(invoiceAmountDetailGetDTO.getInvoiceId(),invoiceAmountDetailGetDTO.getCorpid());
            if(Objects.nonNull(invoiceEntityExt)){
                invoiceAmountDetailGetDTO.setIsEdit(BasicConstant.ONE);
                JSONObject data = invoiceEntityExt.getData();
                originId = data.getLong(InvoiceEnum.ORIGIN_ID.getAttr());
                redIdAndOrigialList.add(originId);
            }
        }

        if(Objects.nonNull(invoiceAmountDetailGetDTO.getInvoiceId())){
            redIdAndOrigialList.add(invoiceAmountDetailGetDTO.getInvoiceId());
        }
        //红冲的时候直接去找所有红冲 红冲编辑时去找被红冲的这个发票下面的所有红冲
        if(redFlag){
            if(Objects.nonNull(invoiceAmountDetailGetDTO.getInvoiceId()) && invoiceAmountDetailGetDTO.getInvoiceId() > 0L) {
                String esData = StringConstant.JSON_DATA + StringConstant.POINT;
                BoolQueryBuilder boolQueryBuilder = boolQuery();
                if(Objects.equals(invoiceAmountDetailGetDTO.getIsRed(),BasicConstant.ONE) && Objects.equals(invoiceAmountDetailGetDTO.getIsEdit(),BasicConstant.ONE)) {
                    boolQueryBuilder.filter(termQuery(esData + InvoiceEnum.ORIGIN_ID.getAttr(), originId));
                }else {
                    boolQueryBuilder.filter(termQuery(esData + InvoiceEnum.ORIGIN_ID.getAttr(), invoiceAmountDetailGetDTO.getInvoiceId()));
                }
                boolQueryBuilder.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, invoiceAmountDetailGetDTO.getCorpid()));
                List<String> fieldList = new ArrayList<>();
                fieldList.add(StringConstant.DATA_ID);
                //查询出这个发票下面的所有红冲
                List<PaasFormDataEntityExt> redPurchaseInvoiceList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_INVOICE, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList);
                if(CollectionsUtil.isNotEmpty(redPurchaseInvoiceList)){
                    for(PaasFormDataEntityExt paasFormDataEntityExt : redPurchaseInvoiceList){
                        redIdAndOrigialList.add(paasFormDataEntityExt.getDataId());
                    }
                }
            }
        }
        List<InvoiceAmountDetailDTO> amountDetail = new ArrayList<>();
        Map<Long,Double> contractInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long,Double> paymentInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long,Double> paymentSheetInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        SalesInvoiceAmountHandleDTO salesInvoiceAmountHandleDTO = new SalesInvoiceAmountHandleDTO();
        List<JSONObject> userList = new ArrayList<>();
        if(Objects.equals(invoiceAmountDetailGetDTO.getIsGetDetail(),BasicConstant.ONE)){
            salesInvoiceAmountHandleDTO.setIsGetDetail(BasicConstant.ONE);
        }
        //第一部查询客户
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid",invoiceAmountDetailGetDTO.getCorpid());
        param.put("del",DelEnum.NORMAL.getDel());
        param.put("idIn",invoiceAmountDetailGetDTO.getCustomerIdList());
        List<CustomerEntityExt> customerEntityExts = customerModel.findEntitys(param);
        if(CollectionsUtil.isNotEmpty(customerEntityExts)) {
            for(CustomerEntityExt customerEntityExt : customerEntityExts) {
                JSONObject data = customerEntityExt.getData();
                JSONObject jsonObject = new JSONObject();
                jsonObject.put(BasicConstant.ID,customerEntityExt.getId());
                jsonObject.put(BasicConstant.NAME, FastJsonHelper.getStringOrDefaultFromFormData(data, CustomerManagementEnum.NAME.getAttr(),""));
                userList.add(jsonObject);
            }
            salesInvoiceAmountHandleDTO.setCustomerList(userList);
        }
        //第二步查询采购合同 和 合同的开票 记录
        if(CollectionsUtil.isNotEmpty(invoiceAmountDetailGetDTO.getContractIdList())) {
            param.put("idIn",invoiceAmountDetailGetDTO.getContractIdList());
            List<ContractEntityExt> contractEntityExts = contractModel.findEntitys(param);
            contractEntityExts = InvoiceCommonHelp.sortEntityById(invoiceAmountDetailGetDTO.getContractIdList(), contractEntityExts,ContractEntityExt.class);
            salesInvoiceAmountHandleDTO.setContractEntityExts(contractEntityExts);
            param.remove("idIn");
            param.put("contractIdIn", invoiceAmountDetailGetDTO.getContractIdList());
            if (Objects.equals(invoiceAmountDetailGetDTO.getIsEdit(), BasicConstant.ONE)) {
                param.put("invoiceIdNot", invoiceAmountDetailGetDTO.getInvoiceId());
            }else if(Objects.equals(invoiceAmountDetailGetDTO.getFormRed(),BasicConstant.ONE)){
                if(redIdAndOrigialList.size() > BasicConstant.ZERO) {
                    param.put("invoiceIdIn", redIdAndOrigialList);
                }
            }
            param.put("isCancel",BasicConstant.ZERO);
            List<InvoiceRelationshipEntity> invoiceRelationshipEntities = invoiceRelationshipModel.findEntitys(param);
            if(CollectionsUtil.isNotEmpty(invoiceRelationshipEntities)) {
                for (InvoiceRelationshipEntity invoiceRelationshipEntity : invoiceRelationshipEntities) {
                    if(Objects.equals(invoiceAmountDetailGetDTO.getIsRed(),BasicConstant.ONE) && Objects.equals(invoiceAmountDetailGetDTO.getIsEdit(),BasicConstant.ONE)){
                        if(!redIdAndOrigialList.contains(invoiceRelationshipEntity.getInvoiceId())){
                            continue;
                        }
                    }
                    AddMapHelp.addMapNormal(contractInvoiceAmountMap,invoiceRelationshipEntity.getContractId(),invoiceRelationshipEntity.getMoney());
                }
                salesInvoiceAmountHandleDTO.setContractInvoiceAmountMap(contractInvoiceAmountMap);
            }
        }
        //第三步查询付款单 付款计划
        if(CollectionsUtil.isNotEmpty(invoiceAmountDetailGetDTO.getPaymentIdList())){
            param.clear();
            param.put("corpid",invoiceAmountDetailGetDTO.getCorpid());
            param.put("del",DelEnum.NORMAL.getDel());
            param.put("idIn",invoiceAmountDetailGetDTO.getPaymentIdList());
            List<PaymentEntityExt> paymentEntityExts = paymentModel.findEntitys(param);
            paymentEntityExts = InvoiceCommonHelp.sortEntityById(invoiceAmountDetailGetDTO.getPaymentIdList(), paymentEntityExts,PaymentEntityExt.class);
            salesInvoiceAmountHandleDTO.setPaymentEntityExts(paymentEntityExts);
            param.remove("idIn");
            param.put("paymentIdIn", invoiceAmountDetailGetDTO.getPaymentIdList());
            if (Objects.equals(invoiceAmountDetailGetDTO.getIsEdit(), BasicConstant.ONE)) {
                param.put("invoiceIdNot", invoiceAmountDetailGetDTO.getInvoiceId());
            } else if (Objects.equals(invoiceAmountDetailGetDTO.getFormRed(), BasicConstant.ONE)) {
                if (redIdAndOrigialList.size() > BasicConstant.ZERO) {
                    param.put("invoiceIdIn", redIdAndOrigialList);
                }
            }
            param.put("isCancel", BasicConstant.ZERO);
            List<InvoiceRelationshipEntity> invoiceRelationshipEntities = invoiceRelationshipModel.findEntitys(param);
            if (CollectionsUtil.isNotEmpty(invoiceRelationshipEntities)) {
                for (InvoiceRelationshipEntity invoiceRelationshipEntity : invoiceRelationshipEntities) {
                    if(Objects.equals(invoiceAmountDetailGetDTO.getIsRed(),BasicConstant.ONE) && Objects.equals(invoiceAmountDetailGetDTO.getIsEdit(),BasicConstant.ONE)){
                        if(!redIdAndOrigialList.contains(invoiceRelationshipEntity.getInvoiceId())){
                            continue;
                        }
                    }
                    AddMapHelp.addMapNormal(paymentInvoiceAmountMap, invoiceRelationshipEntity.getPaymentId(), invoiceRelationshipEntity.getMoney());
                }
                salesInvoiceAmountHandleDTO.setPaymentInvoiceAmountMap(paymentInvoiceAmountMap);
            }

        }
        if(CollectionsUtil.isNotEmpty(invoiceAmountDetailGetDTO.getPaymentSheetIdList())){
            param.clear();
            param.put("corpid",invoiceAmountDetailGetDTO.getCorpid());
            param.put("del",DelEnum.NORMAL.getDel());
            param.put("idIn",invoiceAmountDetailGetDTO.getPaymentSheetIdList());
            List<PaymentSheetEntityExt> paymentSheetEntityExts = paymentSheetModel.findEntitys(param);
            paymentSheetEntityExts = InvoiceCommonHelp.sortEntityById(invoiceAmountDetailGetDTO.getPaymentSheetIdList(), paymentSheetEntityExts,PaymentSheetEntityExt.class);
            salesInvoiceAmountHandleDTO.setPaymentSheetEntityExts(paymentSheetEntityExts);
            param.remove("idIn");
            param.put("paymentSheetIdIn", invoiceAmountDetailGetDTO.getPaymentSheetIdList());
            if (Objects.equals(invoiceAmountDetailGetDTO.getIsEdit(), BasicConstant.ONE)) {
                param.put("invoiceIdNot", invoiceAmountDetailGetDTO.getInvoiceId());
            } else if (Objects.equals(invoiceAmountDetailGetDTO.getFormRed(), BasicConstant.ONE)) {
                if (redIdAndOrigialList.size() > BasicConstant.ZERO) {
                    param.put("invoiceIdIn", redIdAndOrigialList);
                }
            }
            param.put("isCancel", BasicConstant.ZERO);
            List<InvoiceRelationshipEntity> invoiceRelationshipEntities = invoiceRelationshipModel.findEntitys(param);
            if (CollectionsUtil.isNotEmpty(invoiceRelationshipEntities)) {
                for (InvoiceRelationshipEntity invoiceRelationshipEntity : invoiceRelationshipEntities) {
                    if(Objects.equals(invoiceAmountDetailGetDTO.getIsRed(),BasicConstant.ONE) && Objects.equals(invoiceAmountDetailGetDTO.getIsEdit(),BasicConstant.ONE)){
                        if(!redIdAndOrigialList.contains(invoiceRelationshipEntity.getInvoiceId())){
                            continue;
                        }
                    }
                    AddMapHelp.addMapNormal(paymentSheetInvoiceAmountMap, invoiceRelationshipEntity.getPaymentSheetId(), invoiceRelationshipEntity.getMoney());
                }
                salesInvoiceAmountHandleDTO.setPaymentSheetInvoiceAmountMap(paymentSheetInvoiceAmountMap);
            }
        }
        if(Objects.equals(invoiceAmountDetailGetDTO.getIsEdit(),BasicConstant.ONE)) {
            if (Objects.nonNull(invoiceAmountDetailGetDTO.getInvoiceId())) {
                Map<Long,Double> oldContractInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                Map<Long,Double> oldPaymentInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                Map<Long,Double> oldPaymentSheetInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                map.put("corpid", invoiceAmountDetailGetDTO.getCorpid());
                map.put("del", DelEnum.NORMAL.getDel());
                map.put("invoiceId", invoiceAmountDetailGetDTO.getInvoiceId());
                map.put("isCancel",BasicConstant.ZERO);
                List<InvoiceRelationshipEntity> invoiceRelationshipEntities = invoiceRelationshipModel.findEntitys(map);
                if(CollectionsUtil.isNotEmpty(invoiceRelationshipEntities)){
                    for(InvoiceRelationshipEntity invoiceRelationshipEntity : invoiceRelationshipEntities){
                        //如果销项发票关联了合同，但是关系表中没有数据，证明它是点击关联合同进行的操作
                        if(Objects.equals(invoiceRelationshipEntity.getContractId(),0L)){
                            salesInvoiceAmountHandleDTO.setContractEntityExts(new ArrayList<>());
                        }
                        if(!Objects.equals(invoiceRelationshipEntity.getContractId(),0L)){
                            AddMapHelp.addMapNormal(oldContractInvoiceAmountMap,invoiceRelationshipEntity.getContractId(),invoiceRelationshipEntity.getMoney());
                        }
                        if(!Objects.equals(invoiceRelationshipEntity.getPaymentId(),0L)){
                            AddMapHelp.addMapNormal(oldPaymentInvoiceAmountMap,invoiceRelationshipEntity.getPaymentId(),invoiceRelationshipEntity.getMoney());
                        }
                        if(!Objects.equals(invoiceRelationshipEntity.getPaymentSheetId(),0L)){
                            AddMapHelp.addMapNormal(oldPaymentSheetInvoiceAmountMap,invoiceRelationshipEntity.getPaymentSheetId(),invoiceRelationshipEntity.getMoney());
                        }
                    }
                    salesInvoiceAmountHandleDTO.setOldContractInvoiceAmountMap(oldContractInvoiceAmountMap);
                    salesInvoiceAmountHandleDTO.setOldPaymentInvoiceAmountMap(oldPaymentInvoiceAmountMap);
                    salesInvoiceAmountHandleDTO.setOldPaymentSheetInvoiceAmountMap(oldPaymentSheetInvoiceAmountMap);
                    salesInvoiceAmountHandleDTO.setIsEdit(invoiceAmountDetailGetDTO.getIsEdit());
                }
            }
        }
        if(Objects.nonNull(invoiceAmountDetailGetDTO.getIsRed())){
            salesInvoiceAmountHandleDTO.setIsRed(invoiceAmountDetailGetDTO.getIsRed());
        }
        if(Objects.nonNull(invoiceAmountDetailGetDTO.getFormRed())){
            salesInvoiceAmountHandleDTO.setIsRed(invoiceAmountDetailGetDTO.getFormRed());
        }
        amountDetail = InvoiceCommonHelp.commonPackageInvoiceAmountDetail(salesInvoiceAmountHandleDTO);
        InvoiceAmountDetailVO invoiceAmountDetailVO = new InvoiceAmountDetailVO();
        invoiceAmountDetailVO.setAmountDetail(amountDetail);
        return invoiceAmountDetailVO;
    }

    @Override
    public JSONArray approveGetSalesAmountDetail(String corpid, Integer businessType, JSONObject data, Long dataId, String saasNeedPoJo) throws XbbException {
        InvoiceAmountDetailGetDTO invoiceAmountDetailGetDTO = InvoiceCommonHelp.getSalesAmountDetailsByInvoiceData(dataId,data);
        invoiceAmountDetailGetDTO.setCorpid(corpid);
        invoiceAmountDetailGetDTO.setBusinessType(businessType);
        Long originId = FastJsonHelper.getLongOrDefaultFromFormData(data,InvoiceEnum.ORIGIN_ID.getAttr(),0L);
        //红冲新建时
        boolean isAdd = Objects.isNull(dataId) || dataId == 0L;
        if(isAdd && originId >0L){
            invoiceAmountDetailGetDTO.setFormRed(BasicConstant.ONE);
            invoiceAmountDetailGetDTO.setInvoiceId(originId);
        }
        //编辑时
        if(Objects.nonNull(dataId) && dataId >0L && originId <=0L){
            invoiceAmountDetailGetDTO.setIsEdit(BasicConstant.ONE);
        }
        //红冲编辑
        if(Objects.nonNull(dataId) && dataId>0L && originId >0L){
            invoiceAmountDetailGetDTO.setIsRed(BasicConstant.ONE);
            invoiceAmountDetailGetDTO.setIsEdit(BasicConstant.ONE);
        }
        InvoiceAmountDetailVO invoiceAmountDetailVO = getInvoiceAmountDetail(invoiceAmountDetailGetDTO);
        JSONArray amountDetail = JSONArray.parseArray(JSONArray.toJSONString(invoiceAmountDetailVO.getAmountDetail()));
        if(Objects.equals(invoiceAmountDetailGetDTO.getFormRed(),BasicConstant.ONE) || (Objects.equals(invoiceAmountDetailGetDTO.getIsRed(),BasicConstant.ONE) && Objects.equals(invoiceAmountDetailGetDTO.getIsEdit(),BasicConstant.ONE))){
            InvoiceCommonHelp.getMinusAmountFormRedInvoice(data,amountDetail,originId,BasicConstant.ZERO,businessType);
        }
        //任何时候都重新计算一遍
        Map<Long, Double> invoiceMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        JSONObject jsonObject = JSONObject.parseObject(saasNeedPoJo);
        JSONArray saasNeedPojoAmountDetail = jsonObject.getJSONArray(PaasConstant.AMOUNTDETAIL);
        if (CollectionsUtil.isNotEmpty(saasNeedPojoAmountDetail)) {
            for (int i = 0; i < saasNeedPojoAmountDetail.size(); i++) {
                JSONObject amountObj = saasNeedPojoAmountDetail.getJSONObject(i);
                if (Objects.nonNull(amountObj)) {
                    if (amountObj.containsKey(InvoiceConstant.INVOICE_AMOUNT)) {
                        if (CollectionsUtil.isNotEmpty(amountObj.getJSONArray(InvoiceConstant.PAYMENT))) {
                            JSONObject paymentObj = amountObj.getJSONArray(InvoiceConstant.PAYMENT).getJSONObject(BasicConstant.ZERO);
                            if (Objects.nonNull(paymentObj)) {
                                invoiceMap.put(paymentObj.getLong(BasicConstant.ID), amountObj.getDouble(InvoiceConstant.INVOICE_AMOUNT));
                            }
                        } else if (CollectionsUtil.isNotEmpty(amountObj.getJSONArray(InvoiceConstant.PAYMENTSHEET))) {
                            JSONObject paymentSheetObj = amountObj.getJSONArray(InvoiceConstant.PAYMENTSHEET).getJSONObject(BasicConstant.ZERO);
                            if (Objects.nonNull(paymentSheetObj)) {
                                invoiceMap.put(paymentSheetObj.getLong(BasicConstant.ID), amountObj.getDouble(InvoiceConstant.INVOICE_AMOUNT));
                            }
                        } else if (CollectionsUtil.isNotEmpty(amountObj.getJSONArray(InvoiceConstant.CONTRACT))) {
                            JSONObject contractObj = amountObj.getJSONArray(InvoiceConstant.CONTRACT).getJSONObject(BasicConstant.ZERO);
                            if (Objects.nonNull(contractObj)) {
                                invoiceMap.put(contractObj.getLong(BasicConstant.ID), amountObj.getDouble(InvoiceConstant.INVOICE_AMOUNT));
                            }
                        }
                    }else {
                        if(CollectionsUtil.isNotEmpty(amountObj.getJSONArray(InvoiceEnum.PAYMENT_ID.getAttr()))){
                            JSONObject paymentObj = amountObj.getJSONArray(InvoiceEnum.PAYMENT_ID.getAttr()).getJSONObject(BasicConstant.ZERO);
                            if(Objects.nonNull(paymentObj)){
                                invoiceMap.put(paymentObj.getLong(BasicConstant.ID),amountObj.getDouble(InvoiceEnum.TOTAL_MONEY.getAttr()));
                            }
                        }else if(CollectionsUtil.isNotEmpty(amountObj.getJSONArray(InvoiceEnum.PAYMENT_SHEET_ID.getAttr()))){
                            JSONObject paymentSheetObj = amountObj.getJSONArray(InvoiceEnum.PAYMENT_SHEET_ID.getAttr()).getJSONObject(BasicConstant.ZERO);
                            if(Objects.nonNull(paymentSheetObj)){
                                invoiceMap.put(paymentSheetObj.getLong(BasicConstant.ID),amountObj.getDouble(InvoiceEnum.TOTAL_MONEY.getAttr()));
                            }
                        }else if(CollectionsUtil.isNotEmpty(amountObj.getJSONArray(InvoiceEnum.CONTRACT_ID.getAttr()))){
                            JSONObject contractObj = amountObj.getJSONArray(InvoiceEnum.CONTRACT_ID.getAttr()).getJSONObject(BasicConstant.ZERO);
                            if(Objects.nonNull(contractObj)){
                                invoiceMap.put(contractObj.getLong(BasicConstant.ID),amountObj.getDouble(InvoiceEnum.TOTAL_MONEY.getAttr()));
                            }
                        }
                    }
                }
            }
        }
        double sumAmount = 0D;
        double contractUnInvoiceAmount = 0D;
        Set<Long> contractIdSet = new HashSet<>();
        if(CollectionsUtil.isNotEmpty(amountDetail)){
            for (int j = 0; j < amountDetail.size(); j++) {
                JSONObject amountObj = amountDetail.getJSONObject(j);
                JSONArray contractJsonArray = amountObj.getJSONArray(InvoiceConstant.CONTRACT);
                if (Objects.nonNull(contractJsonArray) && contractJsonArray.size() > BasicConstant.ZERO) {
                    Long contractId = contractJsonArray.getJSONObject(BasicConstant.ZERO).getLongValue(BasicConstant.ID);
                    contractIdSet.add(contractId);
                }
            }
            if (CollectionsUtil.isNotEmpty(contractIdSet)) {
                List<ContractEntityExt> contractEntityExts = contractModel.findEntitysByIdIn(corpid, BasicConstant.ZERO, new ArrayList<>(contractIdSet));
                for (ContractEntityExt contractEntityExt : contractEntityExts) {
                    double tempContractUnInvoiceAmount = contractEntityExt.getData().getDoubleValue(ContractEnum.UN_INVOICE_AMOUNT.getAttr());
                    contractUnInvoiceAmount = Arith.add(tempContractUnInvoiceAmount, contractUnInvoiceAmount);
                }
            }
            for (int i = 0; i < amountDetail.size(); i++) {
                JSONObject amountObj = amountDetail.getJSONObject(i);
                if(Objects.nonNull(amountObj)){
                    if (CollectionsUtil.isNotEmpty(amountObj.getJSONArray(InvoiceConstant.PAYMENT))) {
                        JSONObject paymentObj = amountObj.getJSONArray(InvoiceConstant.PAYMENT).getJSONObject(BasicConstant.ZERO);
                        if(Objects.nonNull(paymentObj)) {
                            Long paymentId = paymentObj.getLong(BasicConstant.ID);
                            amountObj.put(InvoiceConstant.INVOICE_AMOUNT, invoiceMap.getOrDefault(paymentId, 0D));
                        }
                    }else if (CollectionsUtil.isNotEmpty(amountObj.getJSONArray(InvoiceConstant.PAYMENTSHEET))) {
                        JSONObject paymentSheetObj = amountObj.getJSONArray(InvoiceConstant.PAYMENTSHEET).getJSONObject(BasicConstant.ZERO);
                        if(Objects.nonNull(paymentSheetObj)) {
                            Long paymentSheetId = paymentSheetObj.getLong(BasicConstant.ID);
                            amountObj.put(InvoiceConstant.INVOICE_AMOUNT, invoiceMap.getOrDefault(paymentSheetId, 0D));
                        }
                    }else if(CollectionsUtil.isNotEmpty(amountObj.getJSONArray(InvoiceConstant.CONTRACT))){
                        JSONObject purchaseObj = amountObj.getJSONArray(InvoiceConstant.CONTRACT).getJSONObject(BasicConstant.ZERO);
                        if(Objects.nonNull(purchaseObj)){
                            Long purchaseId = purchaseObj.getLong(BasicConstant.ID);
                            amountObj.put(InvoiceConstant.INVOICE_AMOUNT,invoiceMap.getOrDefault(purchaseId,0D));
                        }
                    }
                }
                if (Objects.equals(BasicConstant.ONE, invoiceAmountDetailGetDTO.getFormRed()) || Objects.equals(BasicConstant.ONE, invoiceAmountDetailGetDTO.getIsRed())) {
                    //红冲新增或者红冲编辑
                    sumAmount = Arith.add(amountObj.getDouble(InvoiceConstant.INVOICE_AMOUNT),sumAmount);
                }else {
                    //这边需要跟合同的可开票金额进行比较一下，不能超过合同的可开票金额
                    double maxInvoiceAmount = amountObj.getDouble(InvoiceConstant.MAX_INVOICE_AMOUNT);
                    sumAmount = Arith.add(maxInvoiceAmount,sumAmount);
                    if (sumAmount > contractUnInvoiceAmount) {
                        sumAmount = contractUnInvoiceAmount;
                    }
                }
            }
            //兼容审批内sumAmount=0的情况，如果为0则读取父发票的发票金额
            if (Objects.equals(sumAmount, 0D)) {
                sumAmount = data.getDoubleValue(InvoiceEnum.TOTAL_MONEY.getAttr());
            }
            for (int i = 0; i < amountDetail.size(); i++) {
                JSONObject amountObj = amountDetail.getJSONObject(i);
                amountObj.put(InvoiceConstant.SUM_AMOUNT,sumAmount);
            }
        }
        return amountDetail;
    }
}
